package com.example.simpleredis.service.impl;

import com.example.simpleredis.dao.UserDao;
import com.example.simpleredis.entity.User;
import com.example.simpleredis.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;

/**
 * @author zhangs
 * @version v1.0
 * @decription
 * @date 2021/4/7 13:33
 **/
// 指定默认缓存区
// 缓存区：key的前缀，与指定的key构成redis的key，如user::10
@CacheConfig(cacheNames = "user")
@Service
public class UserServiceImpl implements UserService {
    private UserDao userDao;

    @Autowired
    public void setUserDao(final UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 注解@Cacheable说明：
     * - 缓存中存在数据时，从缓存中获取
     * - 没有数据时，执行方法，并将返回值保存到缓存中
     * 该注解一般用于查询语句，参数说明
     * - cacheNames：指定缓存区，没有配置时使用@CacheConfig指定的缓存区
     * - key：指定缓存区的key
     * - condition：满足条件缓存数据，支持使用SpEL表达式，如#id ge 20，即id>=20才缓存
     * - unless：满足条件时拒绝缓存
     * SpEL表达式的运算符：eq(==)、lt(<)、le(<=)、gt(>)、ge(>=)
     */
    @Cacheable("userList")
    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    // @CachePut一般用于新增和修改中使用
    // 写入缓存，key一般为user.id
    @CachePut(cacheNames = {"user"}, key = "#user.id")
    @Transactional
    @Override
    public User saveUser(User user) {
        return userDao.save(user);
    }

    // 标注在delete、update方法上面
    @CacheEvict(cacheNames = {"user"}, key = "#id")
    @Transactional
    @Override
    public int updatePassword(Long id, String password) {
        return userDao.updatePassword(id, password);
    }

    // 如果缓存存在，直接读取缓存值，如果缓存不存在调用目标方法并将方法返回值放入缓存
    @Cacheable(cacheNames = {"user"}, key = "#id")
    @Override
    public User findOne(Long id) {
        /* 存在代理，所以需要取出数据重新封装 */
        User user = userDao.getOne(id);
        User user1 = new User();
        BeanUtils.copyProperties(user, user1);
        return user1;
    }
}
